在 JavaScript 中,非同步程式碼的處理一直以來都是個挑戰。過去,我們只能使用回調函式(callbacks)和事件(events)等來處理非同步操作,但只靠這些在開發上其實不總是那麼方便。為了解決這個問題,ES6 引入了 Promise
,而再後來又有了 Async / Await (async function)
,這兩者大大改善了 JavaScript 中的非同步操作的方便性。
Promise
在 ES6 出現,它代表最終完成或失敗的物件。Promise 可以在非同步操作完成後,傳遞成功或錯誤的結果。Promise 的主要目標是提供一個更好的方式來處理非同步操作,讓程式碼更具可讀性、可維護性。在此之前如果有多個非同步操作,容易造成多層巢狀結構的狀況,而 Promise 的優勢就是避免了這個問題,使得程式碼看起來更好理解。
以下是一個 Promise 語法的範例。
const fetchData = () => {
return new Promise((resolve, reject) => {
// 非同步操作
if (data) {
resolve(data);
} else {
reject(error);
}
});
};
fetchData()
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
在這個例子中,fetchData 返回一個 Promise,我們可以使用 .then() 方法來處理成功的情況,使用 .catch() 方法來處理錯誤。
Async / Await
是在 ES8 引入的,它們是建立在 Promise 上的一種語法糖。它讓非同步函式看起來更像是同步的,使得程式碼更加易讀。透過在函式前面加上 async
關鍵字,將其定義為非同步函式,這樣一來函式內部可以使用 await
關鍵字,當執行到帶有 await
的非同步操作時,會暫停此 async 函式的執行,並且等待非同步操作完成並回傳值後,才繼續執行剩下的程式碼。
以下是一個 Async Function 的範例。
function delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
async function fetchData() {
console.log("Start!");
await delay(2000); // 等待 2 秒
console.log("End!");
}
fetchData(); // 輸出 'Start!',並在兩秒後輸出'End!'
在這個範例中,delay 函式回傳一個 Promise,該 Promise 在指定的時間後被解析並回傳。在 fetchData 函式中,我們使用 await delay(2000),因該函式的執行會在此等待 2 秒後才繼續。這種等待不會封鎖整個執行緒,因此其他程式碼可以繼續執行。
Promise 和 Async/Await 是現代 JavaScript 中處理非同步程式碼的主要方法。它們提供了一種更具可讀性和可維護性的方式來處理非同步操作。本篇文章只是大致講解它們的功用,詳細的語法可參考 MDN文件: